<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Es6-6</title>
</head>
<body>
    <script>
        //ES6 迭代器（遍历）Iterator  生成器
        //数据的迭代
        // var arr = [3,4,5,6,7,8];
        // var arr2 = [[3,5],[9,10,1,2,3]]
        // var len = arr.length;
        // for(let i = 0;i<arr2.length;i++){
        //     for(let j = 0;j<arr2[i].length;j++){
        //         console.log(arr2[i][j]);
        //     }
        // }
        
        // arr2.forEach(item=>{
        //     item.forEach(i =>{
        //         console.log(i)
        //     })
        // })




        //重写迭代器 
        //是一个对象，专门为可迭代对象设计的统一接口，用来遍历数据
        //特点
        //每个迭代器 都有next方法 每次执行next返回一个结果对象{value,done}
        //value每次迭代的数据，done迭代时候结束 Boolean
        //每个迭代器有专用指针，开始时指向数据结构的第一个值，每次调用next方法，放回当前值，指针下移
        //每个迭代器都支持for of循环
        // let newArr = [2,3,4];
        // newArr.iterator.next(); {value:2,done:false}
        // newArr.iterator.next(); {value:3,done:false}
        // newArr.iterator.next(); {value:4,done:false}
        // newArr.iterator.next(); {value:undefined,done:true}
        // let arr = [2,3,4];
        // //创建一个可以迭代数组的迭代器
        // function createIterator(arr = []){
        //     let nextIndex = 0;
        //     return {
        //         next(){
        //             if(arr.length - 1 < nextIndex){
        //                 return {
        //                     value:undefined,
        //                     done: true
        //                 }
        //             }else {
        //                 return {
        //                     value:arr[nextIndex ++],
        //                     done:false
        //                 }
        //             }
        //         }
        //     }
        // }
        // var i = createIterator(arr);
        // i.next();//{value: 2, done: false}
        // i.next();//{value: 3, done: false}
        // i.next();//{value: 4, done: false}
        // i.next();//{value: undefined, done: true}





        //默认的Iterator接口   
        //Array Map Set String arguments NodeLists
        //Array Map Set
        //entries(),keys(),values()  //forEach
        // let arr = [2,3,4];
        // let map = new Map([['name','王小宝'],['age',18],['sex','男']])
        // let set = new Set([1,2,3]);
        // let arrEntries = arr.entries();
        // let mapEntries = map.entries();
        // let setEntries = set.entries();
        // //for of 调用entries接口
        // // for(let item of arrEntries){
        // //     console.log(item);
        // //     //[0,2]
        // //     //[1,3]
        // //     //[2,3]
        // // }
        // // for(let item of mapEntries){
        // //     console.log(item);
        // //     //["name", "王小宝"]
        // //     //["age", 18]
        // //     //["sex", "男"]
        // // }
        // // for(let item of setEntries){
        // //     console.log(item);
        // //     //[1, 1]
        // //     //[2, 2]
        // //     //[3, 3]
        // // }
        // let arrKeys = arr.keys();
        // let mapKeys = map.keys();
        // let setKeys = set.keys();
        // for(let key of arrKeys){
        //     console.log(key)
        //     //0
        //     //1
        //     //2
        // }
        // for(let key of mapKeys){
        //     console.log(key)
        //     //name
        //     //age
        //     //sex
        // }
        // for(let key of setKeys){
        //     console.log(key)
        //     //1
        //     //2
        //     //3
        // }
        // let arrValue = arr.values();
        // let mapValue = map.values();
        // let setValue = set.values();
        // for(let value of arrValue){
        //     console.log(value)
        //     //2
        //     //3
        //     //4
        // }
        // for(let value of mapValue){
        //     console.log(value)
        //     //王小宝
        //     //18
        //     //男
        // }
        // for(let value of setValue){
        //     console.log(value)
        //     //1
        //     //2
        //     //3
        // }
        // //所有的迭代器都有[Symbol.iterator]() 属性必须通过中括号 形式访问，返回默认的迭代器
        // for(let item of arr[Symbol.iterator]()){
        //     console.log(item)
        //     //2
        //     //3
        //     //4
        // }


        
        // //entries 迭代器 对于数组返回 [index,value]
        // arrEntries.next();//{value: [0,2], done: false}
        // arrEntries.next();//{value: [1,3], done: false}
        // arrEntries.next();//{value: [2,4], done: false}
        // arrEntries.next();//{value: undefined, done: true}
        // //entries 迭代器 对于Map返回 [key,value]
        // mapEntries.next();//{value:["name","王小宝"],done:false}
        // mapEntries.next();//{value:["age","18"],done:false}
        // mapEntries.next();//{value:["sex","男"],done:false}
        // mapEntries.next();//{value: undefined, done: true}
        // //entries 迭代器 对于Set返回 [key,key]
        // setEntries.next();//{value:[1,1],done:false}
        // setEntries.next();//{value:[2,2],done:false}
        // setEntries.next();//{value:[3,3],done:false}
        // setEntries.next();//{value:undefined,done:true}




        /*
            原理：
            数组中 迭代器中的指针，每次指向下一个索引
            Map Set会把临接链表 转化一个单项链表 指针每次指向一个节点，指针下移
        */
        // let arr = [2,3,4];
        // let map = new Map([['name','王小宝'],['age',18],['sex','男']])
        // let set = new Set([1,2,3]);
        // for(let item of arr){//arr[Symbol.iterator]() => arr.values()
        //     console.log(item)
        //     //2
        //     //3
        //     //4
        // }
        // for(let item of map){//map[Symbol.iterator]() => map.entries()
        //     console.log(item)
        //     //["name", "王小宝"]
        //     // ["age", 18]
        //     // ["sex", "男"]
        // }
        // for(let item of set){//set[Symbol.iterator]() => set.keys()
        //     console.log(item)
        //     //1
        //     //2
        //     //3
        // }
        //对象是不是可迭代的
        // let obj = {};
        // obj[Symbol.iterator]().next() //报错  不能迭代
    




    
        //生成器 Generator
        //用于生成迭代器
        //生成器是函数 *   yield
        //  function* createIterator(){
        //     console.log("第一次")
        //     yield 1;
        //     console.log("第二次")
        //     yield 2;
        //     console.log("第三次")
        //     yield 3;
        //  }
        //  var i = createIterator();
        //  i.next();



        //把大象装冰箱
        //open loadElephant close
        // open(()=>{
        //     load(()=>{
        //         close()
        //     })
        // })
        
        // function open(){
        //     setTimeout(() => {
        //         console.log("打开冰箱门")
        //     }, 1000);
        // }

        // function load(){
        //     setTimeout(() => {
        //         console.log("把大象装进去")
        //     }, 1000);
        // }

        // function close(){
        //     setTimeout(() => {
        //         console.log("关闭冰箱门")
        //     }, 1000);
        // }
        // function* loadElephant(){
        //     yield open();
        //     yield load();
        //     yield close();
        // }
        // let process = loadElephant();
        // process.next();//打开冰箱门
        // process.next();//把大象装进去
        // process.next();//关闭冰箱门





        //吃橘子
        //吸收 扒皮 吃
        // function washHands(){
        //     console.log('洗手中');
        //     setTimeout(() => {
        //         process.next('一双干净的手');
        //     }, 2000);
        // }
        // function peeling(){
        //     console.log('扒橘子中');
        //     setTimeout(() => {
        //         process.next('一个扒完皮的橘子');
        //     }, 2000);
        // }
        // function eat(){
        //     console.log('吃橘子中');
        //     setTimeout(() => {
        //         process.next('好吃');
        //     }, 2000);
        // }
        // function* eatOrange(){
        //     let result = `${yield washHands()}  ${yield peeling()}  ${yield eat()}`;
        // }
        // let process = eatOrange();
        // process.next();





        //委托迭代器 yield *
        //遍历数组和字符串
        // function* show(arr,string){
        //     yield *arr;
        //     yield *string;
        // }
        // let i = show([1,2,3],'IUY');
        // for (const item of i) {
        //     console.log(item)
        // }



        
    </script>
</body>
</html>